home *** CD-ROM | disk | FTP | other *** search
- IF NOT lasm
- .printx * CPXCIF.ASM *
- ENDIF ;NOT lasm
- ; KERMIT - (Celtic for "FREE")
- ;
- ; This is the CP/M-80 implementation of the Columbia University
- ; KERMIT file transfer protocol.
- ;
- ; Version 4.0
- ;
- ; Copyright June 1981,1982,1983,1984,1985
- ; Columbia University
- ;
- ; Originally written by Bill Catchings of the Columbia University Center for
- ; Computing Activities, 612 W. 115th St., New York, NY 10025.
- ;
- ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
- ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
- ; others.
- ;
- ; This file contains the system dependent part for Cifer systems, and
- ; is based on code contributed by John Shearwood of Birmingham
- ; University. This file was originally CPXTOR.ASM but now an
- ; FAMILY file on its own.
- ;
- ; This file has code that supports Cifer 1886/2886 systems, running
- ; either CP/M Version 2.2 or 3.0, and driving the VL or AUX port.
- ; xxx is a three letter abbrev. for the system you are adding.
- ;
- ; revision history:
- ;
- ; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with
- ; CPXCOM.ASM.
- ;
- ; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK.
- ; His edits ar based on the former CPXTOR.ASM family file.
- ;
- ; edit 4, Apr 7 1987, JA Shearwood. Add support for Cifer Aux port.
- ; edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus
- ;
- ; Keep module name, edit number, and last revision date in memory.
- family: db 'CPXCIF.ASM (2) 14-Jul-87 $'
- ;
- ; Assembly time message to let me know I'm building the right version.
- ; LASM generates an 'S' error along with the message, which is messy, but
- ; better than trying to put everything inside a IF m80 OR mac80 conditional,
- ; because LASM doesn't like nested IF's, either.
-
- IF cifer
- .printx * Assembling Kermit-80 for Cifer 1886 *
- ENDIF
-
- IF cifer3
- .printx * with CP/M Plus
- ENDIF
-
- IF cifaux
- .printx * with AUX port
- ENDIF
-
- ;
- ;=========================================================================
- ; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
- ;
- ;bits 6+7 LIST field
- ; 0 LIST is Teletype device (TTY:)
- ; 1 LIST is CRT device (CRT:)
- ; 2 LIST is Lineprinter (LPT:)
- ; 3 LIST is user defined (UL1:)
- ;
- ;bits 4+5 PUNCH field
- ; 0 PUNCH is Teletype device (TTY:)
- ; 1 PUNCH is high speed punch (PUN:)
- ; 2 PUNCH is user defined #1 (UP1:)
- ; 3 PUNCH is user defined #2 (UP2:)
- ;
- ;bits 2+3 READER field
- ; 0 READER is Teletype device (TTY:)
- ; 1 READER is high speed reader (RDR:)
- ; 2 READER is user defined #1 (UR1:)
- ; 3 READER is user defined #2 (UR2:)
- ;
- ;bits 0+1 CONSOLE field
- ; 0 CONSOLE is console printer (TTY:)
- ; 1 CONSOLE is CRT device (CRT:)
- ; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
- ; LIST = Output
- ; 3 CONSOLE is user defined (UC1:)
- ;
- ;=========================================================================
-
- iobyte EQU 03H ;Location of I/O byte
-
- IF cifer ;[13]
- batio equ 80h ; tty: as console
- defio equ 81h ; crt: as console
- z80 SET TRUE ; although it really is...
- ENDIF;cifer [13]
-
- defesc EQU ']'-100O ;The default escape character.
-
- ; Select initial setting for VT-52 emulation flag.
- vtval EQU 1
-
- IF iobyt ; only CP/M 2.2 and VL port use coniob in CPXCOM
- ; rest use this one
- coniob: db 0 ; default console bit pattern
- ENDIF ;iobyt
-
-
-
- sysxin: ;system initialisation not covered by sysinit
- mvi a,defio
- sta coniob
-
- IF cifer AND NOT cifaux ; [JAS] Not if AUX port
- lxi d,ciferi
- call prtstr
- ENDIF ;cifer AND NOT cifaux
-
- IF cifaux ; [JAS] Only Aux Port
- lhld 00047h ; Get address of CIOPS table
- lxi d,6fh
- dad d ; Calculate address of SETLNSPD
- shld cifiop
- inx h
- inx h
- inx h
- shld ciflod ; Next entry LODEF
- lxi d,81h-72h
- dad d ; Calculate address of LIDEF
- shld ciflid
- lhld 00045h ; Get address of SYSPTRS table
- lxi d,12h ; Offset for LIDEF pointer
- dad d ; Add to table address
- mov e,m ; Get low byte LIDEF pointer
- inx h
- mov d,m ; Get high byte LIDEF pointer
- push d
- inx h ; LIPARM pointer next
- mov a,m ; Get low byte of LIPARM pointer
- sta ciptbl ; Keep
- inx h
- mov a,m ; Get high byte
- sta ciptbl+1 ; Keep
- lxi d,1eh-15h ; Offset to LODEF
- dad d
- mov e,m ; Low byte
- inx h
- mov d,m ; High byte
- inx h ; LOPARM is next entry
- mov a,m
- sta coptbl ; Keep low byte LOPARM
- inx h
- mov a,m
- sta coptbl+1 ; Keep high byte
- ; Now set up port for no parity 8 bits xon/xoff protocol both ways
- xchg ; LODEF into hl register
- push h ; Needed later
- mvi a,0
- mov m,a ; Clear byte 0
- inx h
- mov m,a ; Clear byte 1
- inx h
- mvi a,099h ; XON/XOFF protocol, 8bits, no parity
- mov m,a ; Flag into byte 2
- pop h ; Restore address of LODEF
- ciflod equ $+1
- call $ ; LODEF routine (poked above)
- pop h ; LIDEF (PUSHed from de earlier)
- push h ; Needed later
- mvi a,0
- mov m,a ; Clear byte 0
- inx h
- mov m,a ; Clear byte 1
- inx h
- mvi a,099h ; XON/XOFF protocol, 8bits, no parity
- mov m,a ; Flag into byte 2
- pop h ; Restore address of LIDEF
- ciflid equ $+1
- call $ ; LIDEF routine (poked above)
- lhld ciptbl ; Get current input speed
- mov a,m
- sta speed
- sta speed+1
- mov e,a
- mov d,a
- call sysspd ; Make sure ip and op are the same
- ENDIF; cifer AND cifaux
-
- ret ; return from system-dependent routine
-
- ;
- ;
- ; system-dependent termination processing
- ; If we've changed anything, this is our last chance to put it back.
- sysexit:
-
- IF cifer AND NOT cifaux
- lxi d,cifero
- call prtstr
- ENDIF;cifer AND NOT cifaux
-
- ret
-
- ;
- ; system-dependent processing for start of CONNECT command
- ;
- syscon:
- ret
-
- conmsg: ; Messages printed when entering transparent (CONNECT) mode:
- ;
- ;
- ; syscls - system-dependent close routine
- ; called when exiting transparent session.
- ;
- syscls:
- ret
- ;
- ;
- ; sysinh - help for system-dependent special functions.
- ; called in response to <escape>?, after listing all the
- ; system-independent escape sequences.
- ;
- sysinh: lxi d,inhlps ; we got options...
- call prtstr ; print them.
-
- ret
-
-
- ;additional, system-dependent help for transparent mode
- ; (two-character escape sequences)
- inhlps:
-
- ; [16] [18] have added super brain and Torch to the list of Breaking machines.
-
- IF (cifer AND NOT cifaux)
- db cr,lf,'B Transmit a BREAK'
- ENDIF ;(cifer AND NOT cifaux)
- db '$' ;[hh] table terminator
-
- ;
- ; sysint - system dependent special functions
- ; called when transparent escape character has been typed;
- ; the second character of the sequence is in A (and in B).
- ; returns:
- ; non-skip: sequence has been processed
- ; skip: sequence was not recognized
- sysint: ani 137O ; convert lower case to upper, for testing...
-
- ; [19] have added superbrain and torch to the list
-
- IF (cifer AND NOT cifaux)
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
- ENDIF ;(cifer AND NOT cifaux)
-
- jmp rskp ; take skip return - command not recognized.
-
- ;
-
- IF (cifer AND NOT cifaux)
- sendbr: lxi d,brkmes ; send a break by sending esc * "
- call prtstr ; send to screen => breaks to port
- ret
- ENDIF;cifer
-
- ; sysflt - system-dependent filter.
- ; called with the character in E.
- ; preserves bc, de, hl.
- ; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
- sysflt:
- mov a,e ; get character for testing
- ret
-
- ; mdmflt - modem filter [30]
- ; called with character to be sent to printer in E
- ; with parity set as appropriate.
- ; return with accumulator = 0 do do nothing,
- ; <> 0 to send char in E.
- mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
- ; prtflt - printer filter [30]
- ; called with character to be sent to printer in E
- ; returns with a = 0 to do nothing
- ; a <> 0 to print it.
- ;
- ; this routine for those printer that automatically insert
- ; a lf on cr, or cr for lf. Should this be shifted to
- ; the system indep. stuff, in say 4.06?
- prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
- ;
- ;
- ; system-dependent processing for BYE command.
- ; for apmmdm, heath, and lobo, hang up the phone.
- sysbye:
- ret
- ;
- ; This is the system-dependent command to change the baud rate.
- ; DE contains the two-byte value from the baud rate table; this
- ; value is also stored in 'speed'.
- sysspd:
-
- IF (cifer AND NOT cifaux); This one is wierd..
- ; send an escape string to the screen to set rate.
- push d ; Save the data returned
- lxi d,cifbrt ; send the start of the escape string (esc ?)
- call prtstr ;
- pop psw ; get data into a (and flags>..)
- inr a ; need to send (a+1-1) 'N' to screen
- push psw ; we will need the data again
- call cifnos ; send a set of Ns to the screen
- pop psw ; (which then sets the VL line on the screen
- call cifnos ; processor card)
- call prcrlf ; cr will terminate.. a crlf is handy
- ret
-
- cifnos: dcr a ; if result = 0 then done
- jz cifno1 ; if done then say 'Y' for yes.
- push psw
- mvi e,'N' ; else send a string of Ns to screen processor
- mvi c,dconio
- call bdos
- pop psw
- jmp cifnos
- cifno1: mvi e,'Y'
- mvi c,dconio
- call bdos
- ret ; sent a sring of 0 or more N then a Y
-
- cifbrt: db esc,'?$' ; start setting baud rate string
- ENDIF ;cifer AND NOT cifaux
-
- IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling
- ;CIOPS routine
- ; Set up speed byte in first location of tables
- lhld coptbl ; Now sort out baud rate
- mov a,e ; That's output speed
- mov m,a
- xchg
- lhld ciptbl
- mov m,a ; Input speed
- ; Call CIOPS routine SETLNSPD with tables in appropriate rp's
- cifiop equ $+1
- call $ ; Poked by sysinit
- ret
-
- coptbl: dw 0
- ciptbl: dw 0
- ENDIF; cifaux
-
- ;
- ; Speed tables
- ; (Note that speed tables MUST be in alphabetical order for later
- ; lookup procedures, and must begin with a value showing the total
- ; number of entries. The speed help tables are just for us poor
- ; humans.
-
- ; db string length,string,divisor (2 identical bytes or 1 word)
- ; [Toad Hall]
-
- IF cifer
- spdtbl: db 10h ;16 entries
- db 03h,'110$', 02h,02h
- db 04h,'1200$', 07h,07h
- db 05h,'134.5$', 03h,03h
- db 03h,'150$', 04h,04h
- db 04h,'1800$', 08h,08h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2000$', 09h,09h
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 05h,05h
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 00h,00h
- db 03h,'600$', 06h,06h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 01h,01h
- db 04h,'9600$', 0eh,0eh
-
- sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
- ENDIF;cifer
-
- ; The following conditionals were once a huge if not statement. There
- ; wasn't enough room to add the lobo to the list, so it had to be broken
- ; into 2, which you can't do with an if not. I redid it as two ifs and
- ; applied them to those that wouldn't set baud. [Hal Hostetler]
- ;
- ; This is the system-dependent SET PORT command.
- ; HL contains the argument from the command table.
- sysprt:
- IF iobyt
- mov a,m ;Get the I/O byte
- sta prtiob ;Save the desired IO byte for this port
- inx h ;Point at next entry
- mov a,m ;Get the output function
- sta prtfun ;Save it
- ENDIF;iobyt
-
- ret
- ;
- ;
- ;
- ; Port tables for GENERIC CPM 2.2
- IF gener
- ; help text
- prhtbl: db cr,lf,'CRT device'
- db cr,lf,'PTR device'
- db cr,lf,'TTY device'
- db cr,lf,'UC1 device'
- db cr,lf,'UR1 device'
- db cr,lf,'UR2 device$'
-
- ; command table
- prttbl: db 06H ;Six devices to choose from
- db 03H,'CRT$'
- dw crtptb
- db 03H,'PTR$'
- dw ptrptb
- db 03H,'TTY$'
- dw ttyptb
- db 03H,'UC1$'
- dw uc1ptb
- db 03H,'UR1$'
- dw ur1ptb
- db 03H,'UR2$'
- dw ur2ptb
-
- ; port entry table
- ; table entries are:
- ; db iobyte-value, BDOS output function, reserved
- crtptb: db crtio,conout,0
- ptrptb: db ptrio,punout,0
- ttyptb: db ttyio,conout,0
- uc1ptb: db uc1io,conout,0
- ur1ptb: db ur1io,punout,0
- ur2ptb: db ur2io,punout,0
- ENDIF;gener
-
- ;
- ;
- IF cifer ; no ports yet...
- prttbl EQU 0
- prhtbl EQU 0 ;
- ENDIF; cifer
-
- IF iobyt
- prtfun: db punout ;Function to use for output to comm port
- prtiob: db batio ;I/O byte to use for communicating
- ENDIF;iobyt
-
- IF NOT (iobyt OR lobo OR cifer) ;[hh]
- prttbl equ 0 ; SET PORT is not supported
- prhtbl equ 0
- ENDIF;NOT (iobyt OR lobo OR cifer)
-
- ;
- ;
- ; selmdm - select modem port
- ; selcon - select console port
- ; selmdm is called before using inpmdm or outmdm;
- ; selcon is called before using inpcon or outcon.
- ; For iobyt systems, diddle the I/O byte to select console or comm port;
- ; For Decision I, switches Multi I/O board to console or modem serial
- ; port. [Toad Hall]
- ; For the rest, does nothing.
- ; preserves bc, de, hl.
- selmdm:
- IF iobyt
- lda prtiob ;Set up for output to go to the comm port
- sta iobyte ;Switch byte directly
- ENDIF;iobyt
-
- ret
-
- selcon:
- IF iobyt
- lda coniob ;Set up for output to go to the console port
- sta iobyte ;Switch directly
- ENDIF;iobyt
-
- ret
- ;
- ; Get character from console, or return zero.
- ; result is returned in A. destroys bc, de, hl.
- ;
- inpcon:
- IF NOT iobyt
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ENDIF;NOT iobyt
-
- IF iobyt
- call bconst ;Get the status
- ora a ;Anything there?
- rz ;No, forget it
- call bconin ;Yes, get the character
- ENDIF;iobyt
- ret
- ;
- ;
- ; Output character in E to the console.
- ; destroys bc, de, hl
- ;
- outcon:
-
- IF NOT iobyt
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
- ENDIF;NOT iobyt
-
- IF iobyt
- mov c,e ;Character
- call bcnout ;to Console
- ENDIF;iobyt
- ret
- ;
- ;
- ; outmdm - output a char from E to the modem.
- ; the parity bit has been set as necessary.
- ; returns nonskip; bc, de, hl preserved.
- outmdm:
- IF inout
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
- ENDIF;inout
-
- IF iobyt
- ;**** Note that we enter from outpkt with the I/O byte already set up for
- ; output to go to the comm port
- push h
- push b
- lda prtfun ;Get the output function
- mov c,a ;Into C
- call bdos ;And output the character
- pop b
- pop h
- ret
- ENDIF;iobyt
-
- IF cifer3 ; [JAS]
- push h
- push b
- mvi c,auxout ;Output to the aux output device
- call bdos
- pop b
- pop h
- ret
- ENDIF;cifer3
-
-
- ;
- ;
- ; get character from modem; return zero if none available.
- ; for IOBYT systems, the modem port has already been selected.
- ; destroys bc, de, hl.
- inpmdm:
- IF iobyt
- call bconst ;Is Char at COMM-Port?
- ora a ;something there?
- rz ; return if nothing there
- call bconin ; data present. read data.
- ENDIF;iobyt
-
- IF inout
- ;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
- ENDIF;inout
-
- IF cifer3 ; [JAS]
- mvi c,auxist
- call bdos ;is char at auxin?
- ora a ;something there?
- rz ;no
- mvi c,auxin
- call bdos ;read char from auxin
- ENDIF;cifer3
-
- ret ; return with character in A
-
-
- ;
- ; flsmdm - flush comm line.
- ; Modem is selected.
- ; Currently, just gets characters until none are available.
-
- flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-
- ;
- ;
- ; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
- lptstat:
- IF iobyte ;[33]
- call bprtst ; get status
- ENDIF ;iobyte[33]
- IF NOT iobyte ;[33]
- xra a ; assume it is ok.. this may not be necessary
- ENDIF ;iobyte [33]
- ret
- ;
- ;
- ; outlpt - output character in E to printer
- ; console is selected.
- ; preserves de.
- outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
- IF NOT iobyte
- mvi c,lstout
- call bdos ;Char to printer
- ENDIF;NOT iobyt
- IF iobyt
- mov c,e
- call blsout
- ENDIF;iobyt
-
- outlp1: pop d ; restore saved register pair
- ret
- ;
- ;
- ; Screen manipulation routines
- ; csrpos - move to row B, column C
- ;
- ; csrpos for terminals that use a leadin sequence followed
- ; by (row + 31.) and (column + 31.)
- ;
- IF cifer ; [14] cifer does it colums then rows.. swap b and c
- csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,l ; [obs] get column
- adi (' '-1) ; space is column one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,h ; [obs] get row
- adi (' '-1) ; space is row one
- mov e,a
- jmp outcon ; output it and return
- ENDIF; cifer
-
- ;
- ;
- ; delchr - make delete look like a backspace. Unless delete is a printing
- ; character, we just need to print a backspace. (we'll output clrspc
- ; afterwards)
- ; For Kaypro and Vector General, delete puts a blotch on the screen.
- ; For Apple and Osborne 1, delete moves but doesn't print.
- delchr:
- mvi e,bs
- call outcon
-
- ; erase the character at the current cursor position
- clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
- ; erase the current line
- clrlin: lxi d,eralin
- jmp prtstr
-
- ; erase the whole screen, and go home. preserves b (but not c)
- clrtop: lxi d,erascr
- jmp prtstr
-
-
- IF cifer AND NOT cifaux ;[13]
- ttytyp: db 'Cifer 1886 (Parity set to space only)$'
- ENDIF; cifer AND NOT cifaux
-
- IF cifaux ;JAS
- ttytyp: db ' Cifer 1886 $'
- ENDIF; cifaux
-
- IF cifer ;[JAS]
- sysver: db ' Cifer 1886 $' ;
- outlin: db esc,'J',cr,lf,tab,tab,'$'
- eralin: db esc,'^K$' ;Clear to end of line.
- erascr: db esc,'J$' ;Clear screen and go home.
- curldn: db esc,'P$' ;Cursor lead-in
- ttab: ;Table start location.
- ta: db esc,'A$',0 ;Cursor up.
- tb: db esc,'@$',0 ;Cursor down.
- tc: db esc,'C$',0 ;Cursor right.
- td: db esc,'D$',0 ;Cursor left.
- te: db esc,'J',0,0 ;Clear screen and home cursor
- tf: db '$',0,0,0 ;(can't) Enter Graphics mode
- tg: db '$',0,0,0 ;(can't) Exit Graphics mode
- th: db esc,'H$',0 ;Cursor home.
- ti: db esc,'@$',0 ;reverse linfeed
- tj: db esc,'B$',0 ;Clear to end of screen
- tk: db esc,'K$',0 ;Clear to end of line.
- ENDIF;cifer
- ;
- IF cifer AND NOT cifaux ;[JAS]
- ; Setup string for the Cifer.. called as a prtstr param. from sysinit
- ciferi: db esc,'/' ;Setup cifer for on line
- db esc,'*[' ; direct mode on
- db esc,'%' ; protocol on host line on
- db esc,'*~x' ; protocol is xon/xoff
- db esc,'*(' ; protocol out on host is xon/xoff
- db esc,'? NNNY',cr ; set VL port to space parity
- ; It cannot do NONE.. Thanks a lot
- db '$' ; all done
- ; Finish string for the Cifer.. called as a prtstr param. from sysexit
- cifero: db esc,'&' ; Host input protocol off
- db esc,'*)' ; Host output protocol off
- db esc,'*]' ; Direct mode off
- db esc,'\' ; Setup cifer for off line
- db '$'
- ; Break string for cifer VL port.
- brkmes: db esc,'*"$' ;Send a break command string
- ENDIF;cifer AND NOT cifaux [13]
-
- ovlend equ $ ; End of overlay
-
- END
-